/*
 *  Copyright (c) 2009, Hugo Augusto Alves
 *  All rights reserved.
 * 
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of the Hugo Augusto Alves nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 * 
 *  THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.liteml.parser.blocks;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import org.liteml.exceptions.InvalidListItemException;
import org.liteml.parser.LiteUtils;

/**
 *
 * @author Hugo
 */
public class LiteList extends LiteBlock {

    public static enum ListType {

        BULLETED, NUMBERED
    }

    private ArrayList<LiteListItem> items = new ArrayList<LiteListItem>();

    @Override
    public Type getType() {
        return Type.LIST;
    }

    @Override
    public String parse(LiteUtils.Target t) {
        StringBuilder sb = new StringBuilder();
        Deque<String> closeTags = new ArrayDeque<String>();
        switch (t) {
            case HTML:
                if (items.size() == 0) {
                    return "";
                }
                int previousDepth = -1;
                ListType previousType = null;
                for (LiteListItem item : items) {
                    int currentDepth = item.getDepth();
                    ListType currentType = item.getType();

                    if (previousType != currentType) {
                        changeList(sb, closeTags, currentType);
                    } else if (previousDepth < currentDepth) {
                        for (int i = currentDepth - previousDepth; i > 0; i--) {
                            changeList(sb, closeTags, currentType);
                        }
                    } else if (previousDepth > currentDepth) {
                        for (int i = previousDepth - currentDepth; i > 0; i--) {
                            sb.append(closeTags.pop());
                        }
                    }
                    sb.append("<li>");
                    sb.append(item.getText());
                    sb.append("</li>");
                    previousDepth = item.getDepth();
                    previousType = item.getType();
                }

                while(closeTags.size() > 0) {
                    sb.append(closeTags.pop());
                }
                return sb.toString();
            case PLAIN:
            default:
                // TODO: acertar o plain da list
                for (LiteListItem liteListItem : items) {
                    sb.append(liteListItem.getText());
                    sb.append("\n");
                }
                return sb.toString();
        }
    }

    public LiteList(String str) {
        String[] lines = str.split("\n");
        for (String line : lines) {
            LiteListItem item = null;
            try {
                item = new LiteListItem(line);
            } catch (InvalidListItemException ex) {
                ex.printStackTrace();
            }
            if (item != null) {
                items.add(item);
            }
        }
    }

    private void changeList(StringBuilder sb, Deque<String> closeTags, ListType currentType) {
        if (currentType == ListType.BULLETED) {
            sb.append("<ul>");
            closeTags.push("</ul>");
        } else if (currentType == ListType.NUMBERED) {
            sb.append("<ol>");
            closeTags.push("</ol>");
        }

    }
}
